package com.pig4cloud.pigx.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.customize.enums.AbnormalEnum;
import com.pig4cloud.pigx.common.customize.exception.DuckweedException;
import com.pig4cloud.pigx.common.customize.i18n.util.MessageUtils;
import com.pig4cloud.pigx.system.constant.EmailTemplateTypeEnum;
import com.pig4cloud.pigx.system.dto.ArticleInformationDTO;
import com.pig4cloud.pigx.system.util.SendEmailUtil;
import com.pig4cloud.pigx.user.constant.RedisMessageType;
import com.pig4cloud.pigx.user.entity.RechargeRecord;
import com.pig4cloud.pigx.user.entity.User;
import com.pig4cloud.pigx.user.mapper.UserMapper;
import com.pig4cloud.pigx.user.service.EmailService;
import com.pig4cloud.pigx.user.util.WalletEmailSender;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.pig4cloud.pigx.user.constant.I18nMessages.*;


/**
 * @date:2022/11/18
 */
@Service
@RequiredArgsConstructor
public class EmailServiceImpl implements EmailService {

	/**
	 * RedisKeyEnum
	 */
	private final StringRedisTemplate stringRedisTemplate;
	/**
	 * 平台用户
	 */
	private final UserMapper userMapper;

	/**
	 * 发送邮箱工具类
	 */
	private final SendEmailUtil sendEmailUtil;

	private final WalletEmailSender walletEmailSender;

	/**
	 * 发送验证码
	 *
	 * @param user    邮箱信息
	 * @param massage 邮件类型
	 * @return
	 */
	@Override
	public R<String> sendEmail(User user, String massage,Map<String, String> textContentCode) {

		// 邮箱格式验证
		R<String> emailFormatVerification = sendEmailUtil.emailFormatVerification(user.getEmail());
		if (emailFormatVerification.getCode() != 0) {
			return emailFormatVerification;
		}

		R<String> result;
		if (massage.equals(RedisMessageType.Customer_Registration)
				|| massage.equals(RedisMessageType.Customer_Modify_Email)
				|| massage.equals(RedisMessageType.Customer_Modify_Address)
				|| massage.equals(RedisMessageType.Customer_Modify_MONEY_PASSWORD)
				|| massage.equals(RedisMessageType.Email_Login)
				|| massage.equals(RedisMessageType.Withdrawal_Request)
		) {
			result = sendVerificationCodeEmail(user, massage,textContentCode);
		} else if(massage.equals(RedisMessageType.Withdrawal_Success)) {
			DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
			String dateStr = LocalDateTime.now().format(format);
			Map<String,String> titleCode = new HashMap<>(1);
			titleCode.put("${time}",dateStr);
			result = sendTrueEmail(titleCode, textContentCode, user.getEmail(), massage, null);
		} else {
			//邮箱模板类型不存在
			return R.failed(MessageUtils.get(EMAIL_TEMPLATE_TYPE_DOSE_NOT_EXIST));
		}
		// 发送失败
		if (result.getCode() != 0) {
			return result;
		}
		return R.ok("发送成功");
	}

	/**
	 * 发送邮件(替换参数)
	 * @param titleCode		<${参数名}，参数>  邮件标题替换参数集合
	 * @param textContentCode	<${参数名}，参数>  内容邮件替换参数集合
	 * @param email		收件人邮箱
	 * @param massage message
	 * @param language	语言
	 * @return
	 */
	private R sendTrueEmail(Map<String, String> titleCode, Map<String, String>textContentCode,
							String email, String massage, String language) {
		//获取文章中的邮件模板
		ArticleInformationDTO articleInformationDTO = new ArticleInformationDTO();
		//邮箱模板类型
		String articleTypeCode = EmailTemplateTypeEnum.findArticleTypeCodeByCode(massage);
		if (articleTypeCode == null) {
			//邮箱模板类型不存在
			return R.failed(MessageUtils.get(EMAIL_TEMPLATE_TYPE_DOSE_NOT_EXIST));
		}
		articleInformationDTO.setArticleTypeCode(articleTypeCode);
		//邮箱模板语言，当前语言为空则返回中文
		if (language != null && !language.isEmpty()) {
			articleInformationDTO.setLanguageId(language);
		} else {
			articleInformationDTO.setLanguageId("zh_CN");
		}
		return sendEmailUtil.sendEmail(titleCode, textContentCode, email, articleInformationDTO);

	}

	/**
	 * 发送含有验证码的邮件
	 */
	private R<String> sendVerificationCodeEmail(User user, String massage,Map<String, String> textContentCode) {

		//判断邮箱是否重复发送
		String emailVerificationCode = stringRedisTemplate.opsForValue()
				.get(user.getEmail() + " massage = " + massage);
		if (emailVerificationCode != null && !emailVerificationCode.isEmpty()) {
			return R.failed(MessageUtils.get(EMAIL_HAS_BEEN_SUBMITTED));
		}

		//邮箱注册、修改邮箱 时判断用户是否注册
		if (RedisMessageType.Customer_Registration.equals(massage)) {
			//查询数据库中邮箱是否存在
			Long email = userMapper.selectCount(new QueryWrapper<User>()
					.eq("email", user.getEmail()));
			if (email > 0) {
				return R.failed("该邮箱已注册");
			}
		}
		if (RedisMessageType.Customer_Modify_Email.equals(massage)) {
			Long email = userMapper.selectCount(new QueryWrapper<User>()
					.eq("email", user.getEmail()));
			if (email < 0) {
				throw new DuckweedException(AbnormalEnum.MSG.OPTIONS_USER_NOT_FOUND);
			}
		}

		// 六位随机数验证码
		String code = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));

		// 邮件内容中替换的参数
		textContentCode.put("${code}",code);

		// 发送验证码邮件
		R r = sendTrueEmail(null, textContentCode, user.getEmail(), massage, null);

		if (r.getCode() == 1) {
			return r;
		}
		//向redis里存入数据和设置缓存时间
		stringRedisTemplate.opsForValue().set(
				user.getEmail() + " massage = " + massage,
				code, 60 * 3, TimeUnit.SECONDS);

		return R.ok(MessageUtils.get(SEND_SUCCESSFULLY));
	}

	/**
	 * 发送充值成功/失败邮件
	 * @param record 充值记录
	 */
	@Override
	public void sendRechargeRecordEmail(RechargeRecord record) throws Exception {
		// 用户
		User user = userMapper.selectById(record.getUserId());
		if (user == null || user.getEmail() == null) {
			throw new Exception();
		}
		walletEmailSender.sendRecharge(record,user);
	}


}
